# utils/movie_editor.py
from moviepy import *
from PIL import Image
import os
import re
import natsort
import math
import numpy as np
import subprocess
import asyncio

async def image_to_video(file, duration, fps, base_name, output_video_path):
    def sync_image_to_video():
        img = Image.open(file)
        width, height = img.size
        ratio = width / height
        target_width, target_height = 1280, 720

        if width > target_width or height > target_height:
            if ratio > target_width / target_height:
                new_width = target_width
                new_height = math.floor(new_width / ratio)
            else:
                new_height = target_height
                new_width = math.floor(new_height * ratio)
        else:
            new_width, new_height = width, height

        img = img.resize((new_width, new_height), resample=Image.Resampling.LANCZOS)
        img_clip = ImageClip(np.array(img)).with_duration(duration)
        img_clip = img_clip.with_position('center')

        bg_clip = ColorClip(size=(target_width, target_height), color=(255, 255, 255), duration=duration)
        composite_clip = CompositeVideoClip([bg_clip, img_clip])

        output_filename = f"{base_name}.mp4"
        output_path = os.path.join(output_video_path, output_filename)
        composite_clip.write_videofile(output_path, fps=fps)

        return output_path

    return await asyncio.to_thread(sync_image_to_video)


def concatenate_videos(video_paths, output_path):
    clips = [VideoFileClip(video_path) for video_path in video_paths]
    final_clip = concatenate_videoclips(clips, method="compose")
    final_clip.write_videofile(output_path, codec='libx264', audio_codec='aac',logger=None,threads=4)
    for clip in clips:
        clip.close()

async def merge_audio_video_subtitle(image_video_path, audio_path, srt_path, output_path):
    if not os.path.exists(srt_path):
        raise FileNotFoundError(f"SRT file not found: {srt_path}")

    # 合并音频到视频
    video_clip = VideoFileClip(image_video_path)
    audio_clip = AudioFileClip(audio_path)
    video_with_audio = video_clip.with_audio(audio_clip)

    temp_video_with_audio = os.path.splitext(output_path)[0] + "_temp.mp4"
    video_with_audio.write_videofile(temp_video_with_audio, codec='libx264', audio_codec='aac')

    # 关闭剪辑对象，释放资源
    video_clip.close()
    audio_clip.close()

    # 合并字幕到视频
    command = [
        'ffmpeg',
        '-i', temp_video_with_audio,
        '-vf', f'subtitles={srt_path}',
        '-c:a', 'copy',
        output_path
    ]

    try:
        result = await asyncio.to_thread(subprocess.run, command, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        print(f"FFmpeg Output: {result.stdout.decode('utf-8')}")
        print(f"FFmpeg Error: {result.stderr.decode('utf-8')}")
    except subprocess.CalledProcessError as e:
        print(f"An error occurred while merging video, audio, and subtitles: {e.stderr.decode('utf-8')}")
        raise

    os.remove(temp_video_with_audio)


def images_to_video_with_durations(input_image_path, output_video_path, durations, fps, base_name):
    # 获取所有符合条件的图片，并按文件名中的数字排序
    pattern = r'^' + re.escape(base_name) + r'_(\d+)\.png$'
    image_files = [
        f"{input_image_path}/{file}"
        for file in os.listdir(input_image_path)
        if re.match(pattern, file)
    ]
    image_files = natsort.natsorted(image_files, key=lambda x: int(re.match(pattern, os.path.basename(x)).group(1)))

    # 确定视频的背景尺寸
    target_width, target_height = 1280, 720
    background_size = (target_width, target_height)

    # 为每张图片创建一个单独的剪辑
    clips = []
    for i, file in enumerate(image_files):
        img = Image.open(file)
        width, height = img.size
        ratio = width / height
        if width > target_width or height > target_height:
            if ratio > target_width / target_height:
                new_width = target_width
                new_height = math.floor(new_width / ratio)
            else:
                new_height = target_height
                new_width = math.floor(new_height * ratio)
        else:
            new_width, new_height = width, height

        img = img.resize((new_width, new_height), resample=Image.Resampling.LANCZOS)
        img_clip = ImageClip(np.array(img)).with_duration(durations[i])
        img_clip = img_clip.with_position('center')

        bg_clip = ColorClip(size=background_size, color=(255,255,255), duration=durations[i])
        composite_clip = CompositeVideoClip([bg_clip, img_clip])
        # 添加转场效果（除了最后一个剪辑）
        # if i < len(image_files) - 1:  # 确保不是最后一个剪辑
        #     composite_clip = composite_clip.fx(vfx.fadein, duration=0.3).fx(vfx.fadeout, duration=0.3)

        clips.append(composite_clip)

    # 使用concatenate_videoclips函数将所有剪辑串联起来
    final_clip = concatenate_videoclips(clips, method="compose")

    # 写入视频文件
    output_filename = f"{base_name}.mp4"
    final_clip.write_videofile(os.path.join(output_video_path, output_filename), fps=fps)
